import dayjs from "dayjs";

// 日期格式化
export function parseTime(time: any, pattern?: string) {
  if (arguments.length === 0 || !time) {
    return null;
  }
  const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
  let date;
  if (typeof time === "object") {
    date = time;
  } else {
    if (typeof time === "string" && /^[0-9]+$/.test(time)) {
      time = parseInt(time);
    } else if (typeof time === "string") {
      time = time
        .replace(new RegExp(/-/gm), "/")
        .replace("T", " ")
        .replace(new RegExp(/\.[\d]{3}/gm), "");
    }
    if (typeof time === "number" && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj: { [key: string]: any } = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  return format.replace(
    /{(y|m|d|h|i|s|a)+}/g,
    (result: string, key: string) => {
      let value = formatObj[key];
      // Note: getDay() returns 0 on Sunday
      if (key === "a") {
        return ["日", "一", "二", "三", "四", "五", "六"][value];
      }
      if (result.length > 0 && value < 10) {
        value = "0" + value;
      }
      return value || 0;
    }
  );
}

/**
 * 添加日期范围
 * @param params
 * @param dateRange
 * @param propName
 */
export const addDateRange = (
  params: any,
  dateRange: any[],
  propName?: string
) => {
  const search = params;
  search.params =
    typeof search.params === "object" &&
    search.params !== null &&
    !Array.isArray(search.params)
      ? search.params
      : {};
  dateRange = Array.isArray(dateRange) ? dateRange : [];
  if (typeof propName === "undefined") {
    search.params["beginTime"] = dateRange[0];
    search.params["endTime"] = dateRange[1];
  } else {
    search.params["begin" + propName] = dateRange[0];
    search.params["end" + propName] = dateRange[1];
  }
  return search;
};

// 回显数据字典
export const selectDictLabel = (datas: any, value: number | string) => {
  if (value === undefined) {
    return "";
  }
  const actions = [];
  Object.keys(datas).some((key) => {
    if (datas[key].value == "" + value) {
      actions.push(datas[key].label);
      return true;
    }
  });
  if (actions.length === 0) {
    actions.push(value);
  }
  return actions.join("");
};

// 回显数据字典（字符串数组）
export const selectDictLabels = (datas: any, value: any, separator: any) => {
  if (value === undefined || value.length === 0) {
    return "";
  }
  if (Array.isArray(value)) {
    value = value.join(",");
  }
  const actions: any[] = [];
  const currentSeparator = undefined === separator ? "," : separator;
  const temp = value.split(currentSeparator);
  Object.keys(value.split(currentSeparator)).some((val) => {
    let match = false;
    Object.keys(datas).some((key) => {
      if (datas[key].value == "" + temp[val]) {
        actions.push(datas[key].label + currentSeparator);
        match = true;
      }
    });
    if (!match) {
      actions.push(temp[val] + currentSeparator);
    }
  });
  return actions.join("").substring(0, actions.join("").length - 1);
};

// 字符串格式化(%s )
export function sprintf(str: string) {
  if (arguments.length !== 0) {
    let flag = true,
      i = 1;
    str = str.replace(/%s/g, function () {
      const arg = arguments[i++];
      if (typeof arg === "undefined") {
        flag = false;
        return "";
      }
      return arg;
    });
    return flag ? str : "";
  }
}

// 转换字符串，undefined,null等转化为""
export const parseStrEmpty = (str: any) => {
  if (!str || str == "undefined" || str == "null") {
    return "";
  }
  return str;
};

// 数据合并
export const mergeRecursive = (source: any, target: any) => {
  for (const p in target) {
    try {
      if (target[p].constructor == Object) {
        source[p] = mergeRecursive(source[p], target[p]);
      } else {
        source[p] = target[p];
      }
    } catch (e) {
      source[p] = target[p];
    }
  }
  return source;
};

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export const handleTree = <T>(
  data: any[],
  id?: string,
  parentId?: string,
  children?: string
): T[] => {
  const config: {
    id: string;
    parentId: string;
    childrenList: string;
  } = {
    id: id || "id",
    parentId: parentId || "parentId",
    childrenList: children || "children",
  };

  const childrenListMap: any = {};
  const nodeIds: any = {};
  const tree: T[] = [];

  for (const d of data) {
    const parentId = d[config.parentId];
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
  }

  for (const d of data) {
    const parentId = d[config.parentId];
    if (nodeIds[parentId] == null) {
      tree.push(d);
    }
  }
  const adaptToChildrenList = (o: any) => {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
    }
    if (o[config.childrenList]) {
      for (const c of o[config.childrenList]) {
        adaptToChildrenList(c);
      }
    }
  };

  for (const t of tree) {
    adaptToChildrenList(t);
  }

  return tree;
};

/**
 * 参数处理
 * @param {*} params  参数
 */
export const tansParams = (params: any) => {
  let result = "";
  for (const propName of Object.keys(params)) {
    const value = params[propName];
    const part = encodeURIComponent(propName) + "=";
    if (value !== null && value !== "" && typeof value !== "undefined") {
      if (typeof value === "object") {
        for (const key of Object.keys(value)) {
          if (
            value[key] !== null &&
            value[key] !== "" &&
            typeof value[key] !== "undefined"
          ) {
            const params = propName + "[" + key + "]";
            const subPart = encodeURIComponent(params) + "=";
            result += subPart + encodeURIComponent(value[key]) + "&";
          }
        }
      } else {
        result += part + encodeURIComponent(value) + "&";
      }
    }
  }
  return result;
};

// 返回项目路径
export const getNormalPath = (p: string): string => {
  if (p.length === 0 || !p || p === "undefined") {
    return p;
  }
  const res = p.replace("//", "/");
  if (res[res.length - 1] === "/") {
    return res.slice(0, res.length - 1);
  }
  return res;
};

// 验证是否为blob格式
export const blobValidate = (data: any) => {
  return data.type !== "application/json";
};

/**
 * 删除对象中的空属性
 * @param obj
 * @returns
 */
export const delNullProperty = (obj: any) => {
  if (!obj) return;
  const temp = JSON.parse(JSON.stringify(obj));
  for (const i in temp) {
    // 遍历对象中的属性
    if (temp[i] === undefined || temp[i] === null || temp[i] === "") {
      // 首先除去常规空数据，用delete关键字
      delete temp[i];
    } else if (temp[i].constructor === Object) {
      // 如果发现该属性的值还是一个对象，再判空后进行迭代调用
      if (Object.keys(temp[i]).length === 0) delete temp[i]; // 判断对象上是否存在属性，如果为空对象则删除
      delNullProperty(temp[i]);
    } else if (temp[i].constructor === Array) {
      // 对象值如果是数组，判断是否为空数组后进入数据遍历判空逻辑
      if (temp[i].length === 0) {
        // 如果数组为空则删除
        delete temp[i];
      } else {
        for (let index = 0; index < temp[i].length; index++) {
          // 遍历数组
          if (
            temp[i][index] === undefined ||
            temp[i][index] === null ||
            temp[i][index] === "" ||
            JSON.stringify(temp[i][index]) === "{}"
          ) {
            temp[i].splice(index, 1); // 如果数组值为以上空值则修改数组长度，移除空值下标后续值依次提前
            index--; // 由于数组当前下标内容已经被替换成下一个值，所以计数器需要自减以抵消之后的自增
          }
          if (temp[i].constructor === Object) {
            // 如果发现数组值中有对象，则再次进入迭代
            delNullProperty(temp[i]);
          }
        }
      }
    }
  }
  return temp;
};

/**
 * 判断对象是否是空
 * @param obj
 * @returns
 */
export const isEmpty = (obj: object) => {
  return Object.keys(obj).length === 0;
};

export const listToTagsViewTree = (data: SysMenuEntity[]): tabView[] => {
  const lookup = new Map<string, tabView>();
  const rootNodes: tabView[] = [];
  const tagsview = data.map((item) => menuToTabView(item));
  tagsview.forEach((item) => {
    lookup.set(item?.id || "", item);
  });
  tagsview.forEach((item) => {
    if (item.pid === "0") {
      rootNodes.push(item);
    } else {
      const parent = lookup.get(item.pid || "");
      if (parent) {
        if (!parent.children) {
          parent.children = [];
        }
        parent.children.push(item);
      }
    }
  });
  return rootNodes;
};
const menuToTabView = (data: SysMenuEntity): tabView => {
  const tagsview = {
    path: data.url,
    name: data.name,
    permissions: data.permissions,
    meta: {
      title: data.name,
      icon: data.icon,
    },
    pid: data.pid,
    id: data.id,
    children: data.children?.map((child) => menuToTabView(child)) || [],
  };
  return tagsview;
};
//数组去重
export const uniqueArr = (arr: any[], key: string) => {
  if (Array.isArray(arr) && arr.length > 0 && key) {
    return Array.from(new Set(arr.map((item) => item[key])));
  }
  return [];
};
// 查询树形结构数据父节点
export const findTreeParent = (tree: SysMenuEntity[], id: string) => {
  const pids = [] as string[];
  function traverse(node: SysMenuEntity, nodeId: string) {
    if (node.id === nodeId) {
      return true;
    }
    if (node.children && node.children.length > 0) {
      for (const childNode of node.children) {
        if (traverse(childNode, nodeId)) {
          pids.push(node.id);
          return true;
        }
      }
    }
    return false;
  }
  for (const node of tree) {
    if (traverse(node, id)) {
      pids.push(node.id);
      break;
    }
  }
  return [...new Set(pids)];
};
// 表格数据格式化 - 空值处理
export const formartEmpty = (row: any, column: any, cellValue: any) => {
  if (cellValue == null || cellValue == "") {
    return "-";
  }
  return cellValue;
};
// 表格数据格式化 - 时间格式化
export const formartDateEmpty = (row: any, column: any, cellValue: any) => {
  if (cellValue == null || cellValue == "") {
    return "-";
  }
  return dayjs(cellValue).format("YYYY-MM HH:mm:ss");
};
